#include "configdialog.h"
#include "ui_configdialog.h"
#include "mainwindow.h"
#include "confighelper.h"

#include <QListWidgetItem>
#include <QMessageBox>
#include <QTreeWidget>
#include <QTimer>
#include <QNetworkAccessManager>

static QString SINASUGGEST_URL = "http://suggest3.sinajs.cn/suggest/type=11&key=%1";


ConfigDialog::ConfigDialog(QWidget *parent) :
        QDialog(parent),
        m_ui(new Ui::ConfigDialog)
{
    m_ui->setupUi(this);
    confHelper_ = ((MainWindow*)this->parent())->getConf();

    // 填充List表格
    QStringList stockStrList = confHelper_->getStocksStr().split(',');
    for(int i = 0; i<stockStrList.size(); i++){
        new QListWidgetItem(stockStrList[i].right(6), m_ui->listWidget);
    }

    m_ui->listWidget->setSelectionMode(QAbstractItemView::SingleSelection);

    if(confHelper_->isProxyEnable()){
        m_ui->checkBox->setChecked(true);
        m_ui->leProxy->setDisabled(false);
        m_ui->leProxyPort->setDisabled(false);
    } else {
        m_ui->checkBox->setChecked(false);
        m_ui->leProxy->setDisabled(true);
        m_ui->leProxyPort->setDisabled(true);
    }

    m_ui->leProxy->setText(confHelper_->getProxy());
    m_ui->leProxyPort->setText(QString().setNum(confHelper_->getProxyPort()));

    m_ui->comboBox->addItem(tr("正常"));
    m_ui->comboBox->addItem(tr("永远在最下面"));
    m_ui->comboBox->addItem(tr("永远在最上面"));

    m_ui->comboBox->setCurrentIndex(confHelper_->getWindowStat());

    connect(m_ui->buttonOK, SIGNAL(clicked()), this, SLOT(saveAndExit()));
    connect(m_ui->buttonCancel, SIGNAL(clicked()), this, SLOT(close()));
    connect(m_ui->checkBox, SIGNAL(stateChanged(int)), this, SLOT(proxyEnable(int)));
    connect(m_ui->leProxy, SIGNAL(textChanged(QString)), this, SLOT(proxyChange(QString)));
    connect(m_ui->leProxyPort, SIGNAL(textChanged(QString)), this, SLOT(proxyPortChange(QString)));
    connect(m_ui->btnUp, SIGNAL(clicked()), this, SLOT(moveUp()));
    connect(m_ui->btnDown, SIGNAL(clicked()), this, SLOT(moveDown()));
    connect(m_ui->btnAdd, SIGNAL(clicked()), this, SLOT(addItem()));
    connect(m_ui->btnDel, SIGNAL(clicked()), this, SLOT(deleteItem()));

    popup = new QTreeWidget;
    popup->setColumnCount(1);
    popup->setUniformRowHeights(true);
    popup->setRootIsDecorated(false);
    popup->setEditTriggers(QTreeWidget::NoEditTriggers);
    popup->setSelectionBehavior(QTreeWidget::SelectRows);
    popup->setFrameStyle(QFrame::Box | QFrame::Plain);
    popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    popup->header()->hide();
    popup->installEventFilter(this);
    popup->setMouseTracking(true);

    popup->setWindowFlags(Qt::Popup);
    popup->setFocusPolicy(Qt::NoFocus);
    popup->setFocusProxy(parent);

    connect(popup, SIGNAL(itemClicked(QTreeWidgetItem*, int)),
            SLOT(doneCompletion()));

    timer = new QTimer(this);
    timer->setSingleShot(true);
    timer->setInterval(500);
    connect(timer, SIGNAL(timeout()), SLOT(autoSuggest()));
    connect(m_ui->leStockAdd, SIGNAL(textEdited(QString)), timer, SLOT(start()));

    connect(&networkManager, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(handleNetworkData(QNetworkReply*)));

    QNetworkProxy proxy;
    if (confHelper_->isProxyEnable()){
        proxy.setType(QNetworkProxy::HttpProxy);
        proxy.setHostName(confHelper_->getProxy());
        proxy.setPort(confHelper_->getProxyPort());
        networkManager.setProxy(proxy);
    } else {
        proxy.setType(QNetworkProxy::NoProxy);
        networkManager.setProxy(proxy);
    }

    if (confHelper_->isNotOnToolbar())
        m_ui->checkBox_2->setChecked(true);
    else
        m_ui->checkBox_2->setChecked(false);

}

ConfigDialog::~ConfigDialog()
{
    delete m_ui;
    delete popup;
}

void ConfigDialog::changeEvent(QEvent *e)
{
    QDialog::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void ConfigDialog::proxyEnable(int stat)
{
    if( stat == Qt::Checked) {
        m_ui->leProxy->setDisabled(false);
        m_ui->leProxyPort->setDisabled(false);
        confHelper_->setProxyEnable(true);
    } else if( stat == Qt::Unchecked) {
        m_ui->leProxy->setDisabled(true);
        m_ui->leProxyPort->setDisabled(true);
        confHelper_->setProxyEnable(false);
    }

    ((MainWindow*)this->parent())->isProxyChanged = true;
}

void ConfigDialog::proxyChange(QString proxy)
{
    confHelper_->setProxy(proxy);
    ((MainWindow*)this->parent())->isProxyChanged = true;
}

void ConfigDialog::proxyPortChange(QString port)
{
    confHelper_->setProxyPort(port);
    ((MainWindow*)this->parent())->isProxyChanged = true;
}

void ConfigDialog::saveAndExit()
{
    int i = 1;
    QString stocks = m_ui->listWidget->item(0)->text();
    if(stocks.startsWith("60") ){
        stocks = "sh" + stocks;
    } else if(stocks.startsWith("00") || stocks.startsWith("30")) {
        stocks = "sz" + stocks;
    }

    while(m_ui->listWidget->count()>i){
        QString tmpID;
        QString tmpName;

        QString text = m_ui->listWidget->item(i)->text().left(6);
        if(text.startsWith("60") ){
            tmpID = "sh" + text;
        } else if(text.startsWith("00") || text.startsWith("30")) {
            tmpID = "sz" + text;
        }

        stocks = stocks + "," + tmpID;
        i++;
    }

    if(stocks != confHelper_->getStocksStr()) {
        ((MainWindow*)this->parent())->isStocksChanged = true;
        confHelper_->setStocksStr(stocks);
    }

    confHelper_->setWindowStat(m_ui->comboBox->currentIndex());

    if(m_ui->checkBox_2->isChecked())
        confHelper_->setNotOnToolbar(true);
    else
        confHelper_->setNotOnToolbar(false);

    this->accept();
    this->close();
}

void ConfigDialog::exit()
{
    this->reject();
}

void ConfigDialog::moveUp()
{
    if(m_ui->listWidget->currentItem() && m_ui->listWidget->currentRow() != 0){
        QListWidgetItem *it = m_ui->listWidget->item(m_ui->listWidget->currentRow()-1);
        QString str = it->text();
        it->setText(m_ui->listWidget->currentItem()->text());
        m_ui->listWidget->currentItem()->setText(str);
        m_ui->listWidget->setCurrentRow(m_ui->listWidget->currentRow()-1);
    }
}

void ConfigDialog::moveDown()
{
    if(m_ui->listWidget->currentItem()
        && m_ui->listWidget->currentRow() != m_ui->listWidget->count()-1){
        QListWidgetItem *it = m_ui->listWidget->item(m_ui->listWidget->currentRow()+1);
        QString str = it->text();
        it->setText(m_ui->listWidget->currentItem()->text());
        m_ui->listWidget->currentItem()->setText(str);
        m_ui->listWidget->setCurrentRow(m_ui->listWidget->currentRow()+1);
    }
}

void ConfigDialog::deleteItem()
{
    if(m_ui->listWidget->currentItem()){
        QListWidgetItem *it = m_ui->listWidget->takeItem(m_ui->listWidget->currentRow());
        delete it;
    }
}

void ConfigDialog::addItem()
{
    QString str = m_ui->leStockAdd->text();

    // 需要加入更多的判断，判断是否合法的输入了股票
    if((str.startsWith("60") || str.startsWith("00") || str.startsWith("30")) && str.length() == 6){
        QListWidgetItem *it = new QListWidgetItem();
        it->setText(str);
        m_ui->listWidget->insertItem(0, it);
        m_ui->leStockAdd->clear();
    } else {
        QMessageBox::warning(0, QObject::tr("股票代码不合法"),
                             QObject::tr("股票代码不符合格式，请添加符合格式的代码!只支持60,00,30开头的股票。"));
    }
}

void ConfigDialog::showCompletion(QStringList choices)
{
    if (choices.isEmpty())
        return;

    const QPalette &pal = m_ui->leStockAdd->palette();
    QColor color = pal.color(QPalette::Disabled, QPalette::WindowText);

    popup->setUpdatesEnabled(false);
    popup->clear();
    for (int i = 0; i < choices.count(); ++i) {
        QTreeWidgetItem * item;
        item = new QTreeWidgetItem(popup);
        item->setText(0, choices[i]);
    }
    popup->setCurrentItem(popup->topLevelItem(0));
    popup->resizeColumnToContents(0);

    popup->adjustSize();
    popup->setUpdatesEnabled(true);

    int h = popup->sizeHintForRow(0) * qMin(10, choices.count()) + 3;

    popup->resize(200, h);
    popup->move(m_ui->leStockAdd->mapToGlobal(QPoint(0, m_ui->leStockAdd->height())));
    popup->setFocus();
    popup->show();

}

void ConfigDialog::doneCompletion()
{
    timer->stop();
    popup->hide();
    m_ui->leStockAdd->setFocus();
    QTreeWidgetItem *item = popup->currentItem();
    if (item) {
        m_ui->leStockAdd->setText(item->text(0).left(6));
        QKeyEvent *e;
        e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
        QApplication::postEvent(m_ui->leStockAdd, e);
        e = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Enter, Qt::NoModifier);
        QApplication::postEvent(m_ui->leStockAdd, e);
    }
}


void ConfigDialog::autoSuggest()
{
    if(m_ui->leStockAdd->text().isEmpty())
        return;
    QString str = m_ui->leStockAdd->text();
    QString url = QString(SINASUGGEST_URL).arg(str);
    networkManager.get(QNetworkRequest(QString(url)));
}

void ConfigDialog::handleNetworkData(QNetworkReply *networkReply)
{
    QUrl url = networkReply->url();
    if (!networkReply->error()) {

        QByteArray byteArray = networkReply->readAll();
        QString response = QTextCodec::codecForName("gb2312")->toUnicode(byteArray);

        int start = response.indexOf("\"")+1;
        int end = response.lastIndexOf("\"");
        response = response.mid(start,end-start);

        QStringList choices = response.split(";");

        for(int i = 0; i < choices.size() - 1; i++) {
            QString tmp = choices[i];
            QStringList listTmp = tmp.split(",");
            choices[i] = listTmp[2] + " " + listTmp[4];
        }
        showCompletion(choices);
    }

    networkReply->deleteLater();
}

bool ConfigDialog::eventFilter(QObject *obj, QEvent *ev)
{
    if (obj != popup)
        return false;

    if (ev->type() == QEvent::MouseButtonPress) {
        popup->hide();
        m_ui->leStockAdd->setFocus();
        return true;
    }

    if (ev->type() == QEvent::KeyPress) {

        bool consumed = false;
        int key = static_cast<QKeyEvent*>(ev)->key();
        switch (key) {
        case Qt::Key_Enter:
        case Qt::Key_Return:
            doneCompletion();
            consumed = true;

        case Qt::Key_Escape:
            m_ui->leStockAdd->setFocus();
            popup->hide();
            consumed = true;

        case Qt::Key_Up:
        case Qt::Key_Down:
        case Qt::Key_Home:
        case Qt::Key_End:
        case Qt::Key_PageUp:
        case Qt::Key_PageDown:
            break;

        default:
            m_ui->leStockAdd->setFocus();
            m_ui->leStockAdd->event(ev);
            popup->hide();
            break;
        }

        return consumed;
    }

    return false;
}
